home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / kiss-0.11 / kiss-0 / kiss / src / dochmod.c < prev    next >
C/C++ Source or Header  |  1995-03-23  |  4KB  |  193 lines

  1. #include "kiss.h"
  2.  
  3. static int buildmask (char *s, int *owner, int *setordel, int *readmode,
  4.               int *writemode, int *execmode)
  5. {
  6.     register int
  7.     state = 0;
  8.  
  9.     *owner = 0;
  10.     *readmode = 0;
  11.     *writemode = 0;
  12.     *execmode = 0;
  13.     
  14.     while (*s)
  15.     {
  16.     if (! state)            /* expecting owner info */
  17.     {
  18.         if (*s == 'u')
  19.         *owner |= S_IRWXU;
  20.         else if (*s == 'g')
  21.         *owner |= S_IRWXG;
  22.         else if (*s == 'o')
  23.         *owner |= S_IRWXO;
  24.         else if (*s == 'a')
  25.         *owner |= (S_IRWXU | S_IRWXG | S_IRWXO);
  26.         else if (*s == '-' || *s == '+')
  27.         {
  28.         *owner |= S_IRWXU;
  29.         s--;
  30.         }
  31.         else
  32.         return (0);
  33.         state++;
  34.     }
  35.     else if (state == 1)        /* expecting set or remove info */
  36.     {
  37.         if (*s == '-')
  38.         *setordel = -1;
  39.         else if (*s == '+')
  40.         *setordel = 1;
  41.         else
  42.         return (0);
  43.         state++;
  44.     }
  45.     else if (state == 2)        /* expecting modebits info */
  46.     {
  47.         if (*s == 'r')
  48.         *readmode = 1;
  49.         else if (*s == 'w')
  50.         *writemode = 1;
  51.         else if (*s == 'x')
  52.         *execmode = 1;
  53.         else
  54.         return (0);
  55.     }
  56.     s++;
  57.     }
  58.  
  59.     return (1);                /* successful parsing */
  60. }
  61.  
  62. int dochmod (Stringstack s)
  63. {
  64.     int
  65.     owner,
  66.     setordel,
  67.     readmode,
  68.     writemode,
  69.     execmode,
  70.     newmode;
  71.     register int
  72.     ret = 0,
  73.     octalmode = 0,
  74.     i;
  75.     struct stat
  76.     statbuf;
  77.     
  78.     if (s.nstr < 3)
  79.     error ("Bad commandline.\n"
  80.            "Usage: %s asciimode | octalmode  file(s)\n"
  81.            "Where:\n"
  82.            "    asciimode: the mode to set, use [ugoa][-+][rwx] to:\n"
  83.            "        apply to user(u), group(g), other(o) or all(a)"
  84.                                 " [default:u]\n"
  85.            "        remove(-) or set(+) bits [required],\n"
  86.            "        apply to the read(r), write(w), exec(x) bits\n"
  87.            "    octalmode: mode as an octal number\n"
  88.            "    file(s): the files to process\n"
  89.            , progname);
  90.  
  91.     if (s.str [1][0] >= '0' && s.str [1][0] <= '7')
  92.     {
  93.     if (! sscanf (s.str [1], "%o", &newmode))
  94.         return (warning ("bad octal mode \"%s\"", s.str [1]));
  95.     octalmode++;
  96.     }
  97.     else if (! buildmask (s.str [1], &owner, &setordel, &readmode,
  98.              &writemode, &execmode))
  99.     return (warning ("bad ascii mode \"%s\"", s.str [1]));
  100.  
  101.  
  102.     for (i = 2; i < s.nstr; i++)
  103.     {
  104.     if (stat (s.str [i], &statbuf))
  105.     {
  106.         ret += warning ("cannot stat \"%s\"", s.str [i]);
  107.         continue;
  108.     }
  109.  
  110.     if (octalmode)
  111.     {
  112.         if (chmod (s.str [i], newmode))
  113.         ret += warning ("problems setting octal mode "
  114.                 "%o for file \"%s\"",
  115.                 newmode, s.str [i]);
  116.         continue;
  117.     }
  118.     
  119.     newmode = statbuf.st_mode;
  120.     
  121.     if (owner & S_IRWXU)
  122.     {
  123.         if (setordel == 1)
  124.         {
  125.         if (readmode)
  126.             newmode |= S_IRUSR;
  127.         if (writemode)
  128.             newmode |= S_IWUSR;
  129.         if (execmode)
  130.             newmode |= S_IXUSR;
  131.         }
  132.         else
  133.         {
  134.         if (readmode)
  135.             newmode &= ~S_IRUSR;
  136.         if (writemode)
  137.             newmode &= ~S_IWUSR;
  138.         if (execmode)
  139.             newmode &= ~S_IXUSR;
  140.         }
  141.     }
  142.     
  143.     if (owner & S_IRWXG)
  144.     {
  145.         if (setordel == 1)
  146.         {
  147.         if (readmode)
  148.             newmode |= S_IRGRP;
  149.         if (writemode)
  150.             newmode |= S_IWGRP;
  151.         if (execmode)
  152.             newmode |= S_IXGRP;
  153.         }
  154.         else
  155.         {
  156.         if (readmode)
  157.             newmode &= ~S_IRGRP;
  158.         if (writemode)
  159.             newmode &= ~S_IWGRP;
  160.         if (execmode)
  161.             newmode &= ~S_IXGRP;
  162.         }
  163.     }
  164.     if (owner & S_IRWXO)
  165.     {
  166.         if (setordel == 1)
  167.         {
  168.         if (readmode)
  169.             newmode |= S_IROTH;
  170.         if (writemode)
  171.             newmode |= S_IWOTH;
  172.         if (execmode)
  173.             newmode |= S_IXOTH;
  174.         }
  175.         else
  176.         {
  177.         if (readmode)
  178.             newmode &= ~S_IROTH;
  179.         if (writemode)
  180.             newmode &= ~S_IWOTH;
  181.         if (execmode)
  182.             newmode &= ~S_IXOTH;
  183.         }
  184.     }
  185.  
  186.     if (chmod (s.str [i], newmode))
  187.         ret += warning ("problems setting octal mode %o for file \"%s\"",
  188.                 newmode, s.str [i]);
  189.     }
  190.  
  191.     return (0);
  192. }
  193.